// ValidationAspects
// Written by Mike Saunders
// Released under Microsoft Public License (Ms-PL)
using System;
using System.Linq;
using NUnit.Framework;
using ValidationAspects;
using ValidationAspects.Exceptions;
using ValidationAspects.Factories;

namespace TestValidationAspects
{
	[TestFixture]
	public class TestNotEqualAttribute
	{
		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void Test_constructor_throws_for_null_string_param()
		{
			new NotEqualAttribute(null);
		}

		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void Test_constructor2_throws_for_null_string_param()
		{
			new NotEqualAttribute(null, true);
		}

		[Test]
		public void Test_get_Factory_for_double_param_constructor()
		{
			NotEqual factory = new NotEqualAttribute(100).Factory as NotEqual;
			Assert.IsNotNull(factory);
			Assert.AreEqual(100, factory.Number);
			Assert.IsNull(factory.Text);
		}

		[Test]
		public void Test_get_Factory_for_string_param_constructor()
		{
			NotEqual factory = new NotEqualAttribute("text").Factory as NotEqual;
			Assert.IsNotNull(factory);
			Assert.AreEqual(0, factory.Number);
			Assert.AreEqual("text", factory.Text);
			Assert.IsFalse(factory.IgnoreCase);
		}

		[Test]
		public void Test_get_Factory_for_string_bool_param_constructor()
		{
			NotEqual factory = new NotEqualAttribute("text", true).Factory as NotEqual;
			Assert.IsNotNull(factory);
			Assert.AreEqual(0, factory.Number);
			Assert.AreEqual("text", factory.Text);
			Assert.IsTrue(factory.IgnoreCase);

			factory = (NotEqual)new NotEqualAttribute("text", false).Factory;
			Assert.IsFalse(factory.IgnoreCase);
		}

		[Test]
		public void Test_usage_for_strings()
		{
			Dummy dummy = new Dummy {NotEqualString = "Test"};

			ValidationResult result = dummy.Validate();
			Assert.IsFalse(result.IsValid);
			Assert.AreSame(typeof(ValidateNotEqualException), ((ValidationContextException)result.ValidationException).Flatten().First().GetType());
		}

		[Test]
		public void Test_usage_for_numerics()
		{
			Dummy dummy = new Dummy {NotEqualNumber = 123};

			ValidationResult result = dummy.Validate();
			Assert.IsFalse(result.IsValid);
			Assert.AreSame(typeof(ValidateNotEqualException), ((ValidationContextException)result.ValidationException).Flatten().First().GetType());
		}

		#region Mocks
		public class Dummy
		{
			[NotEqual("test", true)]
			public string NotEqualString { get; set; }

			[NotEqual(123)]
			public int NotEqualNumber { get; set; }
		}
		#endregion
	}
}